package com.fingard.dsp.bank.directbank.cmbc01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directConfig.TaskTimerSet;
import com.fingard.dsp.bank.directbank.bankInterface.IScheduleTask;
import com.fingard.net.FormSubmit;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.*;

public class CMBC01ScheduleTask extends CMBC01Base implements IScheduleTask {
    //inster(主键，渠道，账户ID，账户，是否民生标志，账号类型)
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,OUTREQSEQID,REQSEQID,RESERVE1,RESERVE2) values (?,?,?,?,?,?);";
    private static final String UPDATERECEIPT = "UPDATE REQSEQIDMAPPING SET REQSEQID=?,RESERVE1=?,RESERVE2=? WHERE OUTREQSEQID=?;";

    @Override
    public void execTask(TaskTimerSet timerSet) {
        if (timerSet.taskNameList.contains("pushAccInfo")) {
            pushAccInfo();
        }
    }


    public void pushAccInfo() {
        try {
            WriteBankLogLn("开始获取全球账户信息任务");
            /**
             * 获取组织机构关系
             */
            Map<String, Object> cashPoolTreeMap = new HashMap<String, Object>();
            cashPoolTreeMap = getCashPoolTree();

            /**
             * 获取账户信息
             */
            Map<String, Object> accInfoListMap = new HashMap<String, Object>();
            accInfoListMap = getAccInfoByTree(cashPoolTreeMap);

            /**
             * 组装成JSON格式发给ATS
             */
            StringBuilder json = new StringBuilder();
            json.append("transType=downloadAccInfo&data={");
            String totalNum = accInfoListMap.get("totalNum").toString();
            json.append("\"totalNum\":\"" + totalNum + "\",");
            List<Map<String, Object>> customIdList = new ArrayList<Map<String, Object>>();
            customIdList = (List<Map<String, Object>>) accInfoListMap.get("cashPoolTreelist");
            json.append("\"list\":[");
            for (int i = 0; i < customIdList.size(); i++) {
                json.append("{");
                json.append("\"customId\":\"" + customIdList.get(i).get("customId") + "\",");
                json.append("\"treeNodeId\":\"" + customIdList.get(i).get("treeNodeId") + "\",");
                json.append("\"treeParentNodeId\":\"" + customIdList.get(i).get("treeParentNodeId") + "\",");
                json.append("\"customNameCn\":\"" + customIdList.get(i).get("customNameCn") + "\",");
                json.append("\"upCustomNameCn\":\"" + customIdList.get(i).get("upCustomNameCn") + "\",");
                json.append("\"hasChild\":\"" + customIdList.get(i).get("hasChild") + "\",");
                json.append("\"AccInfoRows\":[");
                List<Map<String, String>> accInfoList = new ArrayList<Map<String, String>>();
                accInfoList = (List<Map<String, String>>) customIdList.get(i).get("AccInfoRows");
                for (int j = 0; j < accInfoList.size(); j++) {
                    json.append("{");
                    json.append("\"accountId\":\"" + accInfoList.get(j).get("accountId") + "\",");
                    json.append("\"account\":\"" + accInfoList.get(j).get("account") + "\",");
                    json.append("\"accName\":\"" + accInfoList.get(j).get("accName") + "\",");
                    json.append("\"accUserBal\":\"" + accInfoList.get(j).get("accUserBal") + "\",");
                    json.append("\"accBal\":\"" + accInfoList.get(j).get("accBal") + "\",");
                    json.append("\"isCmbc\":\"" + accInfoList.get(j).get("isCmbc") + "\",");
                    json.append("\"currencyId\":\"" + accInfoList.get(j).get("currencyId") + "\",");
                    json.append("\"currencyName\":\"" + accInfoList.get(j).get("currencyName") + "\",");
                    json.append("\"bankName\":\"" + accInfoList.get(j).get("bankName") + "\",");
                    json.append("\"countryName\":\"" + accInfoList.get(j).get("countryName") + "\",");
                    json.append("\"accountType\":\"" + accInfoList.get(j).get("accountType") + "\"");
                    json.append("},");
                }
                json.deleteCharAt(json.length() - 1);//删除最后一个逗号
                json.append("]},");
            }
            json.deleteCharAt(json.length() - 1);
            json.append("]}");

            //将数据推送到ATS,使用ATS电子回单地址，ATS使用数据头部transType=downloadAccInfo与电子回单推送区分
            WriteBankLogLn("推送数据到ATS的数据为：" + json.toString());
            String[] data;
            String receiptPushType = FGBiz.dspCenter.dspSet.receiptPushType;

            if ("nbGateway".equals(receiptPushType)) {
                WriteBankLogLn("3.推送给网关的数据" + json.toString());
                data = FormSubmit.receiptInfoSend(json.toString(), this);
                if (data[0].length() == 0 && data[1].equals("ok")) {
                    WriteBankLogLn("推送数据到网关成功,请查看数据");
                } else {
                    WriteBankLogLn("推送数据到网关失败");
                }
            } else {
                data = sendToATS(json.toString());
                if (data[0].length() == 0 && data[1].equals("ok")) {
                    WriteBankLogLn("推送数据到ATS成功,请查看数据");
                } else {
                    WriteBankLogLn("推送数据到ATS失败");
                }
            }
        } catch (Exception e) {
            WriteBankLogLn("推送账户信息出现异常，异常信息：" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 获取账户信息
     */
    public Map<String, Object> getAccInfoByTree(Map<String, Object> cashPoolTreeMap) throws Exception {
        List<Map<String, Object>> cashPoolTreelist = new ArrayList<Map<String, Object>>();
        cashPoolTreelist = (List<Map<String, Object>>) cashPoolTreeMap.get("cashPoolTreelist");
        Connection conn = FGBiz.getLocalDbConn();
        try {
            for (int i = 0; i < cashPoolTreelist.size(); i++) {
                /**
                 * 每个客户编号查询分页查询账号信息，发送报文
                 */
                int tmpNowReadStart = 1;//起始页数
                int tmpNowReadNum = 0;//已查询笔数
                Map<String, Integer> tmpTotalNum = new HashMap<String, Integer>();
                while (tmpNowReadNum == 0 || tmpNowReadNum < tmpTotalNum.get("totalCount")) {
                    //赋值通用参数
                    XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                    //写入通用的头部节点
                    CMBC01Header bankHeader = new CMBC01Header();
                    bankHeader.trnCode = "CBCashPoolAccInfoQry";
                    writeCommonHeader(xmlWriter, bankHeader);
                    xmlWriter.writeStartElement("xDataBody");
                    xmlWriter.writeElementString("trnId", Format.DateTime17Format.format(new Date()));
                    xmlWriter.writeElementString("customId", cashPoolTreelist.get(i).get("customId").toString());
                    //isQryNextLevel  0 - 不查下级账户1 - 查询下级账户
                    xmlWriter.writeElementString("isQryNextLevel", "0");
                    xmlWriter.writeElementString("pageNo", tmpNowReadStart + "");//当前页数
                    xmlWriter.writeElementString("pageSize", getBankConfig().getValueAsString("pageSize"));//每页查询笔数
                    xmlWriter.writeEndDocument();

                    String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());
                    if (tmpRetBkStr[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String tmpRetCode = tmpBkReader.getFirstText("/CMBC/responseHeader/status/code");
                            String tmpRetMessage = tmpBkReader.getFirstText("/CMBC/responseHeader/status/message");
                            if (tmpRetCode.equals("0")) {
                                //符合条件的条数，总明细数
                                String totalCount = tmpBkReader.getFirstText("/CMBC/xDataBody/allNum");
                                if (tmpTotalNum.containsKey("totalCount")) {
                                    if (!tmpTotalNum.get("totalCount").equals(Integer.valueOf(totalCount))) {
                                        WriteBankLogLn("查询客户编号：" + cashPoolTreelist.get(i).get("customId") + "，相同条件前后查出来的总数不一致");
                                        break;
                                    }
                                } else {
                                    if ("0".equals(totalCount)) {
                                        WriteBankLogLn("客户编号：" + cashPoolTreelist.get(i).get("customId") + ",账户数为0");
                                        break;
                                    }
                                    tmpTotalNum.put("totalCount", Integer.valueOf(totalCount));//记录总条数
                                }

                                int readCount = 0;
                                List<Map<String, String>> accInfoDetailList = new ArrayList<Map<String, String>>();
                                while (tmpBkReader.read("/CMBC/xDataBody/List/Map")) {
                                    XElement readXElement = tmpBkReader.readedXElement;
                                    Map<String, String> accInfoDetail = new HashMap<String, String>();
                                    accInfoDetail.put("accountId", readXElement.getSingleText("accountId"));//帐号 ID
                                    accInfoDetail.put("account", readXElement.getSingleText("account"));//帐号
                                    accInfoDetail.put("accName", readXElement.getSingleText("accName"));//账号名称
                                    accInfoDetail.put("accUserBal", readXElement.getSingleText("accUserBal"));//可用余额
                                    accInfoDetail.put("accBal", readXElement.getSingleText("accBal"));//账户余额
                                    accInfoDetail.put("isCmbc", readXElement.getSingleText("isCmbc"));//是否是民生银行标志0-他行账户1-民生银行账户
                                    accInfoDetail.put("accountType", readXElement.getSingleText("accountType"));//账号类型1-境内分行账户；2-境外分行账户；3-他行账户
                                    accInfoDetail.put("currencyId", convertCurToATS(readXElement.getSingleText("currencyName")));//币种ID
                                    accInfoDetail.put("currencyName", readXElement.getSingleText("currencyName"));//币种名称
                                    accInfoDetail.put("bankName", readXElement.getSingleText("bankName"));//开户行名称
                                    accInfoDetail.put("countryName", readXElement.getSingleText("countryName"));//开户行所在国家

                                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                                    //inster(主键，渠道，账户ID，账户，是否民生标志，账号类型)
                                    if (JDBCHelper.update(conn, UPDATERECEIPT, new Object[]{accInfoDetail.get("account"), accInfoDetail.get("isCmbc"), accInfoDetail.get("accountType"), accInfoDetail.get("accountId")}) == 0) {
                                        JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, "CMBC01", accInfoDetail.get("accountId"), accInfoDetail.get("account"), accInfoDetail.get("isCmbc"), accInfoDetail.get("accountType")});
                                    }
                                    accInfoDetailList.add(accInfoDetail);
                                    readCount++;
                                }
                                cashPoolTreelist.get(i).put("AccInfoRows", accInfoDetailList);
                                tmpNowReadNum += readCount;//已查询条数
                                if (Integer.parseInt(totalCount) > tmpNowReadNum) {
                                    //总条数大于已查询条数，说明查询了默认条数的明细
                                    if (readCount != Integer.valueOf(getBankConfig().getValueAsString("pageSize"))) {
                                        WriteBankLogLn("查询客户编号：" + cashPoolTreelist.get(i).get("customId") + ",账户总数大于已查询条数,统计明细有误");
                                        break;
                                    }
                                }
                                if (Integer.parseInt(totalCount) < tmpNowReadNum) {
                                    //总条数小于已查询条数,说明数据异常
                                    WriteBankLogLn("查询客户编号：" + cashPoolTreelist.get(i).get("customId") + ",账户总数小于已查询条数,统计明细有误");
                                    break;
                                }
                                tmpNowReadStart++;//查询起始页加1
                            } else {
                                WriteBankLogLn("查询客户编号：" + cashPoolTreelist.get(i).get("customId") + ",出现问题：" + tmpRetMessage);
                                break;
                            }
                        } else {
                            WriteBankLogLn("查询客户编号" + cashPoolTreelist.get(i).get("customId") + ",出现问题：" + tmpSbMsg.toString());
                            break;
                        }
                    } else {
                        WriteBankLogLn("查询客户编号" + cashPoolTreelist.get(i).get("customId") + ",出现问题：" + tmpRetBkStr[1]);
                        break;
                    }
                }
            }
        } catch (Exception e) {
            WriteBankLogLn("获取账户信息出现异常，异常信息：" + e.getMessage());
            e.printStackTrace();
        } finally {
            conn.close();
        }
        Map<String, Object> newAccInfoMap = new HashMap<String, Object>();
        newAccInfoMap.put("totalNum", cashPoolTreeMap.get("totalNum").toString());
        newAccInfoMap.put("cashPoolTreelist", cashPoolTreelist);
        return newAccInfoMap;
    }

    /**
     * 获取组织机构关系
     */
    public Map<String, Object> getCashPoolTree() {
        WriteBankLogLn("开始获取组织机构关系，得到客户编号");
        Map<String, Object> accInfoMap = new HashMap<String, Object>();
        try {
            //赋值通用参数
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //写入通用的头部节点
            CMBC01Header bankHeader = new CMBC01Header();
            bankHeader.trnCode = "CBCashPoolTreeQry";
            writeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("xDataBody");
            xmlWriter.writeElementString("trnId", Format.DateTime17Format.format(new Date()));
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBC/responseHeader/status/code");
                    String tmpRetMessage = tmpBkReader.getFirstText("/CMBC/responseHeader/status/message");
                    if (tmpRetCode.equals("0")) {
                        String totalNum = tmpBkReader.getFirstText("/CMBC/xDataBody/totalNum");
                        accInfoMap.put("totalNum", totalNum);
                        List<Map<String, Object>> cashPoolTreelist = new ArrayList<Map<String, Object>>();
                        while (tmpBkReader.read("/CMBC/xDataBody/List/Map")) {
                            Map<String, Object> oneNoteAccInfo = new HashMap<String, Object>();
                            oneNoteAccInfo.put("customId", tmpBkReader.readedXElement.getSingleText("customId"));//客户编号
                            oneNoteAccInfo.put("treeNodeId", tmpBkReader.readedXElement.getSingleText("treeNodeId"));//客户关系树节点 ID
                            oneNoteAccInfo.put("treeParentNodeId", tmpBkReader.readedXElement.getSingleText("treeParentNodeId"));//客户关系树父节点 ID
                            oneNoteAccInfo.put("level", tmpBkReader.readedXElement.getSingleText("level"));//客户在整棵树中的所处层级
                            oneNoteAccInfo.put("customNameCn", tmpBkReader.readedXElement.getSingleText("customNameCn"));//客户中文名称
                            String upCustomNameCn = tmpBkReader.readedXElement.getSingleText("upCustomNameCn");
                            oneNoteAccInfo.put("upCustomNameCn", StringHelper.isNullOrEmpty(upCustomNameCn) ? "没有上级客户" : upCustomNameCn);//上级客户中文名称
                            oneNoteAccInfo.put("hasChild", tmpBkReader.readedXElement.getSingleText("hasChild"));//是否具有子节点 true-有子节点 false-无子节点
                            cashPoolTreelist.add(oneNoteAccInfo);
                        }
                        accInfoMap.put("cashPoolTreelist", cashPoolTreelist);
                        WriteBankLogLn("已成功获取组织结构信息");
                    } else {
                        WriteBankLogLn(tmpRetMessage);
                    }
                } else {
                    WriteBankLogLn(tmpSbMsg.toString());
                }
            } else {
                WriteBankLogLn(tmpStrRet[1]);
            }
        } catch (Exception e) {
            WriteBankLogLn("获取组织机构出现异常，异常信息：" + e.getMessage());
            e.printStackTrace();
        }
        return accInfoMap;
    }
}
